package com.uinnova.product.eam.service.asset.impl;

import com.binary.core.lang.StringUtils;
import com.binary.core.util.BinaryUtils;
import com.binary.framework.exception.ServiceException;
import com.binary.jdbc.Page;
import com.uinnova.product.eam.comm.model.es.CEamDiagramRelease;
import com.uinnova.product.eam.comm.model.es.CEamRecentlyView;
import com.uinnova.product.eam.comm.model.es.EamAttention;
import com.uinnova.product.eam.comm.model.es.EamRecentlyView;
import com.uinnova.product.eam.model.RecentlyViewBo;
import com.uinnova.product.eam.model.constants.DiagramConstant;
import com.uinnova.product.eam.service.asset.IAttentionSvc;
import com.uinnova.product.eam.service.asset.IRecentlyViewSvc;
import com.uinnova.product.eam.service.es.IamsEsRecentlyViewDao;
import com.uinnova.product.vmdb.comm.i18n.MessageUtil;
import com.uinnova.project.api.diagram.v2.client.ESDiagramApiClient;
import com.uinnova.project.base.diagram.comm.diagram.EamDiagramQuery;
import com.uinnova.project.base.diagram.comm.model.CVcDiagram;
import com.uinnova.project.base.diagram.comm.model.ESDiagram;
import com.uinnova.project.base.diagram.comm.model.ESSimpleDiagramDTO;
import com.uino.api.client.permission.IUserApiSvc;
import com.uino.bean.permission.base.SysUser;
import com.uino.bean.permission.query.CSysUser;
import com.uino.util.sys.SysUtil;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class RecentlyViewSvcImpl implements IRecentlyViewSvc {

    @Autowired
    private IamsEsRecentlyViewDao iamsEsRecentlyViewDao;
    @Resource
    private ESDiagramApiClient diagramApiClient;

    @Autowired
    private IAttentionSvc attentionSvc;

    @Autowired
    private IUserApiSvc userApiSvc;

    @Autowired
    private com.uinnova.project.service.eam.ESDiagramSvc diagramService;

    private static final String VIEWBUILD = "viewBuild";

    private static final String USERID = "userId";

    private static final String MODIFYTIME = "modifyTime";

    private static final String PLAN_ID = "planId";

    @Override
    public Long saveOrUpdateRecentlyView(CEamRecentlyView ceamRecentlyView) {
        MessageUtil.checkEmpty(ceamRecentlyView, "eamRecentlyView");
        //MessageUtil.checkEmpty(ceamRecentlyView.getViewBuild(), VIEWBUILD);
        //MessageUtil.checkEmpty(ceamRecentlyView.getDiagramId(), "diagramId");
        MessageUtil.checkEmpty(ceamRecentlyView.getUserId(), USERID);
        if (!StringUtils.isBlank(ceamRecentlyView.getDiagramId())) {
            EamRecentlyView eamRecentlyView = new EamRecentlyView();
            BeanUtils.copyProperties(ceamRecentlyView, eamRecentlyView);
            CEamDiagramRelease cdt = new CEamDiagramRelease();
            EamDiagramQuery diagram = new EamDiagramQuery();
            diagram.setDEnergy(ceamRecentlyView.getDiagramId());
            cdt.setDiagram(diagram);
            Long diagramId = diagramApiClient.queryDiagramInfoByEnergy(ceamRecentlyView.getDiagramId());
            if (BinaryUtils.isEmpty(diagramId)) {
                throw new ServiceException("获取发布信息出错!");
            }
            eamRecentlyView.setDiagramId(diagramId);
            BoolQueryBuilder queryBuilder = new BoolQueryBuilder();
            //queryBuilder.must(QueryBuilders.termQuery(VIEWBUILD, eamRecentlyView.getViewBuild()));
            queryBuilder.must(QueryBuilders.termQuery("diagramId", eamRecentlyView.getDiagramId()));
            queryBuilder.must(QueryBuilders.termQuery(USERID, eamRecentlyView.getUserId()));
            List<EamRecentlyView> listByQuery = iamsEsRecentlyViewDao.getListByQuery(queryBuilder);
            if (!CollectionUtils.isEmpty(listByQuery)) {
                eamRecentlyView = listByQuery.get(0);
            }
            return iamsEsRecentlyViewDao.saveOrUpdate(eamRecentlyView);
        }

        if (ceamRecentlyView.getPlanId() != null) {
            EamRecentlyView eamRecentlyView = new EamRecentlyView();
            BeanUtils.copyProperties(ceamRecentlyView, eamRecentlyView);
            BoolQueryBuilder queryBuilder = new BoolQueryBuilder();
            //queryBuilder.must(QueryBuilders.termQuery(VIEWBUILD, eamRecentlyView.getViewBuild()));
            queryBuilder.must(QueryBuilders.termQuery(PLAN_ID, eamRecentlyView.getPlanId()));
            queryBuilder.must(QueryBuilders.termQuery(USERID, eamRecentlyView.getUserId()));
            List<EamRecentlyView> listByQuery = iamsEsRecentlyViewDao.getListByQuery(queryBuilder);
            if (!CollectionUtils.isEmpty(listByQuery)) {
                eamRecentlyView = listByQuery.get(0);
            }
            return iamsEsRecentlyViewDao.saveOrUpdate(eamRecentlyView);
        }
    return null;
    }

    @Override
    public RecentlyViewBo getAllRecentlyDiagram() {
        //获取三天前时间
        Long oneDayTime = getOneDay(3);

        SysUser currentUserInfo = SysUtil.getCurrentUserInfo();
        Long userId = currentUserInfo.getId();
        BoolQueryBuilder queryBuilder = new BoolQueryBuilder();
        queryBuilder.must(QueryBuilders.termQuery(USERID,userId));
        queryBuilder.must(QueryBuilders.rangeQuery("createTime").gte(oneDayTime));
        Page<EamRecentlyView> recentlyViewPage = iamsEsRecentlyViewDao.getSortListByQuery(1, 2000, queryBuilder, MODIFYTIME, false);
        List<EamRecentlyView> recentlyViewList = recentlyViewPage.getData();
        List<Long> diagramIdList = recentlyViewList.stream().filter(view -> !BinaryUtils.isEmpty(view.getViewType()) && view.getViewType() == 1).map(EamRecentlyView :: getDiagramId).collect(Collectors.toList());
        CVcDiagram cVcDiagram = new CVcDiagram();
        if (CollectionUtils.isEmpty(diagramIdList)) {
            RecentlyViewBo recentlyViewBo = new RecentlyViewBo();
            recentlyViewBo.setDiagramDTOList(new ArrayList<>());
            recentlyViewBo.setRecentlyViewList(recentlyViewList);
            return recentlyViewBo;
        }
        cVcDiagram.setIds(diagramIdList.toArray(new Long[0]));
        List<ESDiagram> esDiagrams = diagramService.queryESDiagramList(1l, cVcDiagram, "");
        Map<Long, ESDiagram> diagramMap = esDiagrams.stream().collect(Collectors.toMap(ESDiagram:: getId, item -> item, (v1, v2) -> v2));
        List<ESSimpleDiagramDTO> diagramDTOList = new ArrayList<>();
        Set<String> ownerCodes = esDiagrams.stream().map(ESDiagram::getOwnerCode).collect(Collectors.toSet());
        CSysUser cSysUser = new CSysUser();
        cSysUser.setDomainId(1L);
        cSysUser.setLoginCodes(ownerCodes.toArray(new String[0]));
        cSysUser.setSuperUserFlags(new Integer[]{0, 1});
        List<SysUser> userInfos = userApiSvc.getSysUserByCdt(cSysUser);
        Map<String, SysUser> userMap = userInfos.stream().collect(Collectors.toMap(SysUser::getLoginCode, sysUser -> sysUser, (k1, k2) -> k1));
        for (ESDiagram diagram : esDiagrams) {

            if (!StringUtils.isEmpty(diagram.getIcon1())) {
                diagram.setIcon1(diagram.getIcon1());
            }
            if (diagram.getId() != null) {
                EamAttention eamAttention = attentionSvc.getEamAttention(null, diagram.getId(), userId);
                if (eamAttention != null) {
                    diagram.setIsAttention(DiagramConstant.IS_ATTENTION);
                } else {
                    diagram.setIsAttention(DiagramConstant.NOT_IS_ATTENTION);
                }
            }
            // 兼容异常数据 改用ownerCode查询
            SysUser userInfo = userMap.get(diagram.getOwnerCode());
            if (CollectionUtils.isEmpty(userInfos)) {
                userInfo = new SysUser();
            }
//            Map<Long, List<ESDiagramShareRecordResult>> diagramListMap = null;

            ESSimpleDiagramDTO esSimpleDiagramDTO = new ESSimpleDiagramDTO();
            // 视图
            esSimpleDiagramDTO.setDiagram(diagram);
            // 用户
            esSimpleDiagramDTO.setCreator(userInfo);
            // 分享视图
//            if (!CollectionUtils.isEmpty(diagramListMap)) {
//                esSimpleDiagramDTO.setShareRecords(diagramListMap.get(view.getDiagramId()));
//            }
            diagramDTOList.add(esSimpleDiagramDTO);
        }
        RecentlyViewBo recentlyViewBo = new RecentlyViewBo();
        recentlyViewBo.setDiagramDTOList(diagramDTOList);
        recentlyViewBo.setRecentlyViewList(recentlyViewList);
        return recentlyViewBo;
    }

    @Override
    public RecentlyViewBo getDesignRecentlyDiagram() {
        //获取三天前时间
        Long oneDayTime = getOneDay(3);

        SysUser currentUserInfo = SysUtil.getCurrentUserInfo();
        Long userId = currentUserInfo.getId();
        BoolQueryBuilder queryBuilder = new BoolQueryBuilder();
        queryBuilder.must(QueryBuilders.termQuery(USERID,userId));
        queryBuilder.must(QueryBuilders.rangeQuery("createTime").gte(oneDayTime));
        queryBuilder.must(QueryBuilders.termQuery("viewArchitectureType",1));
        Page<EamRecentlyView> recentlyViewPage = iamsEsRecentlyViewDao.getSortListByQuery(1, 2000, queryBuilder, MODIFYTIME, false);
        List<EamRecentlyView> recentlyViewList = recentlyViewPage.getData();
        List<ESSimpleDiagramDTO> diagramDTOList = new ArrayList<>();
        List<Long> diagramIdList = recentlyViewList.stream().filter(view -> !BinaryUtils.isEmpty(view.getViewType()) && view.getViewType() == 1).map(EamRecentlyView :: getDiagramId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(diagramIdList)) {
            RecentlyViewBo recentlyViewBo = new RecentlyViewBo();
            recentlyViewBo.setDiagramDTOList(diagramDTOList);
            recentlyViewBo.setRecentlyViewList(recentlyViewList);
            return recentlyViewBo;
        }
        CVcDiagram cVcDiagram = new CVcDiagram();
        cVcDiagram.setIds(diagramIdList.toArray(new Long[0]));
        List<ESDiagram> esDiagrams = diagramService.queryESDiagramList(1l, cVcDiagram, "");
        Map<Long, ESDiagram> diagramMap = esDiagrams.stream().collect(Collectors.toMap(ESDiagram :: getId, item -> item, (v1, v2) -> v2));
        Set<String> ownerCodes = esDiagrams.stream().map(ESDiagram::getOwnerCode).collect(Collectors.toSet());
        CSysUser cSysUser = new CSysUser();
        cSysUser.setDomainId(1L);
        cSysUser.setLoginCodes(ownerCodes.toArray(new String[0]));
        cSysUser.setSuperUserFlags(new Integer[]{0, 1});
        List<SysUser> userInfos = userApiSvc.getSysUserByCdt(cSysUser);
        Map<String, SysUser> userMap = userInfos.stream().collect(Collectors.toMap(SysUser::getLoginCode, sysUser -> sysUser, (k1, k2) -> k1));

        for (ESDiagram diagram : esDiagrams) {

            if (!StringUtils.isEmpty(diagram.getIcon1())) {
                diagram.setIcon1(diagram.getIcon1());
            }
            if (diagram.getId() != null) {
                EamAttention eamAttention = attentionSvc.getEamAttention(null, diagram.getId(), userId);
                if (eamAttention != null) {
                    diagram.setIsAttention(DiagramConstant.IS_ATTENTION);
                } else {
                    diagram.setIsAttention(DiagramConstant.NOT_IS_ATTENTION);
                }
            }
            // 兼容异常数据 改用ownerCode查询
            SysUser userInfo = userMap.get(diagram.getOwnerCode());
            if (CollectionUtils.isEmpty(userInfos)) {
                userInfo = new SysUser();
            }
//            Map<Long, List<ESDiagramShareRecordResult>> diagramListMap = null;
            ESSimpleDiagramDTO esSimpleDiagramDTO = new ESSimpleDiagramDTO();
            // 视图
            esSimpleDiagramDTO.setDiagram(diagram);
            // 用户
            esSimpleDiagramDTO.setCreator(userInfo);
            // 分享视图
//            if (!CollectionUtils.isEmpty(diagramListMap)) {
//                esSimpleDiagramDTO.setShareRecords(diagramListMap.get(view.getDiagramId()));
//            }
            diagramDTOList.add(esSimpleDiagramDTO);
        }
        RecentlyViewBo recentlyViewBo = new RecentlyViewBo();
        recentlyViewBo.setDiagramDTOList(diagramDTOList);
        recentlyViewBo.setRecentlyViewList(recentlyViewList);
        return recentlyViewBo;
    }

    @Override
    public void batchCancelRecentlyView(CEamRecentlyView eamRecentlyView) {
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        if (!StringUtils.isEmpty(eamRecentlyView.getDiagramId())) {
            queryBuilder.must(QueryBuilders.termQuery("diagramId.keyword", eamRecentlyView.getDiagramId()));
        }
        if (!CollectionUtils.isEmpty(eamRecentlyView.getPlanIds())) {
            queryBuilder.must(QueryBuilders.termsQuery(PLAN_ID, eamRecentlyView.getPlanIds()));
        }
        List<EamRecentlyView> listByCdt = iamsEsRecentlyViewDao.getListByQuery(queryBuilder);
        if (!CollectionUtils.isEmpty(listByCdt)) {
            iamsEsRecentlyViewDao.deleteByIds(listByCdt.stream().map(EamRecentlyView::getId).collect(Collectors.toList()));
        }
    }

    private Long getOneDay(int day) {
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        calendar.add(Calendar.DATE, -3);
        Long dateTime = Long.valueOf(sdf.format(calendar.getTime()));
        return dateTime;
    }

    @Override
    public List<ESDiagram> findRecentlyViewList(EamRecentlyView eamRecentlyView) {
        MessageUtil.checkEmpty(eamRecentlyView, "eamRecentlyView");
        MessageUtil.checkEmpty(eamRecentlyView.getUserId(), USERID);
        BoolQueryBuilder queryBuilder = new BoolQueryBuilder();
        queryBuilder.must(QueryBuilders.termQuery(USERID, eamRecentlyView.getUserId()));
        queryBuilder.must(QueryBuilders.termQuery("viewType", 1));
        Page<EamRecentlyView> recentlyViewPage = iamsEsRecentlyViewDao.getSortListByQuery(1, 20, queryBuilder, MODIFYTIME, false);
        List<EamRecentlyView> recentlyViewList = recentlyViewPage.getData();
        List<ESDiagram> result = new ArrayList<>();
        if(CollectionUtils.isEmpty(recentlyViewList)){
            return result;
        }
        List<Long> diagramIds = recentlyViewList.stream().map(EamRecentlyView::getDiagramId).distinct().collect(Collectors.toList());
        List<ESDiagram> diagramList = diagramApiClient.getByIds(diagramIds, null, null);
        Map<Long, ESDiagram> diagramMap = diagramList.stream().collect(Collectors.toMap(ESDiagram::getId, each -> each, (k1, k2) -> k2));
        for (EamRecentlyView view : recentlyViewList) {
            ESDiagram diagram = diagramMap.get(view.getDiagramId());
            if(diagram == null){
                continue;
            }
            if (diagram.getId() != null) {
                EamAttention eamAttention = attentionSvc.getEamAttention(null, diagram.getId(), eamRecentlyView.getUserId());
                if (eamAttention != null) {
                    diagram.setIsAttention(DiagramConstant.IS_ATTENTION);
                } else {
                    diagram.setIsAttention(DiagramConstant.NOT_IS_ATTENTION);
                }
            }
            result.add(diagram);
        }
        return result;
    }

    @Override
    public Long cancelRecentlyView(EamRecentlyView eamRecentlyView) {
        CEamRecentlyView cEamRecentlyView = new CEamRecentlyView();
        if (eamRecentlyView.getDiagramId() != null) {
            cEamRecentlyView.setDiagramId(eamRecentlyView.getDiagramId().toString());
        }
        if (eamRecentlyView.getPlanId() != null) {
            cEamRecentlyView.setPlanId(eamRecentlyView.getPlanId());
        }
        List<EamRecentlyView> listByCdt = iamsEsRecentlyViewDao.getListByCdt(cEamRecentlyView);
        if (!CollectionUtils.isEmpty(listByCdt)) {
            iamsEsRecentlyViewDao.deleteByIds(listByCdt.stream().map(EamRecentlyView::getId).collect(Collectors.toList()));
        }
        return 1L;
    }

    @Override
    public void cancelRecentlyViewBatch(List<Long> diagramIds, List<Long> planIds) {
        if (CollectionUtils.isEmpty(diagramIds) && CollectionUtils.isEmpty(planIds)) {
            return;
        }
        BoolQueryBuilder query = QueryBuilders.boolQuery();
        if (!CollectionUtils.isEmpty(diagramIds)) {
            query.should(QueryBuilders.termsQuery("diagramId", diagramIds));
        }
        if (!CollectionUtils.isEmpty(planIds)) {
            query.should(QueryBuilders.termsQuery(PLAN_ID, planIds));
        }
        List<EamRecentlyView> recentlyViews = iamsEsRecentlyViewDao.getListByQuery(query);
        if (!CollectionUtils.isEmpty(recentlyViews)) {
            iamsEsRecentlyViewDao.deleteByIds(recentlyViews.stream().map(EamRecentlyView::getId).collect(Collectors.toList()));
        }
    }

    @Override
    public List<EamRecentlyView> getRecentlyView(Integer buildType) {
        CEamRecentlyView eamRecentlyView = new CEamRecentlyView();
//        eamRecentlyView.setViewBuild(buildType);
        eamRecentlyView.setUserId(SysUtil.getCurrentUserInfo().getId());
        Page<EamRecentlyView> pageInfo = iamsEsRecentlyViewDao.getSortListByCdt(1, 20, eamRecentlyView, MODIFYTIME, false);
        if (pageInfo.getData() == null || pageInfo.getData().size() <= 0) {
            return new ArrayList<>();
        }
        return pageInfo.getData();
    }

    @Override
    public List<EamRecentlyView> getDesignRecentlyView() {
        CEamRecentlyView eamRecentlyView = new CEamRecentlyView();
        eamRecentlyView.setUserId(SysUtil.getCurrentUserInfo().getId());
        eamRecentlyView.setViewArchitectureType(2);
        Page<EamRecentlyView> pageInfo = iamsEsRecentlyViewDao.getSortListByCdt(1, 20, eamRecentlyView, MODIFYTIME, false);
        if (pageInfo.getData() == null || pageInfo.getData().size() <= 0) {
            return new ArrayList<>();
        }
        return pageInfo.getData();
    }

    @Override
    public List<EamRecentlyView> getAllRecentlyList() {
        //获取三天前时间
        Long oneDayTime = getOneDay(3);

        SysUser currentUserInfo = SysUtil.getCurrentUserInfo();
        Long userId = currentUserInfo.getId();
        BoolQueryBuilder queryBuilder = new BoolQueryBuilder();
        queryBuilder.must(QueryBuilders.termQuery(USERID,userId));
        queryBuilder.must(QueryBuilders.rangeQuery("createTime").gte(oneDayTime));
        Page<EamRecentlyView> recentlyViewPage = iamsEsRecentlyViewDao.getSortListByQuery(1, 3000, queryBuilder, MODIFYTIME, false);
        if (CollectionUtils.isEmpty(recentlyViewPage.getData())) {
            return Collections.emptyList();
        }
        return recentlyViewPage.getData();
    }
}
